<template>
  <div>
    <ZoomView
      ref="view"
      class="absolute-full"
      :class="`bg-grey-${$q.dark.isActive ? 9 : 5}`"
      :x="viewCenter.x"
      :y="viewCenter.y"
      :zoom.sync="viewZoom"
      :min-zoom="minViewZoom"
      :max-zoom="maxViewZoom"
      inactive
      @resize="(w, h) => ((viewWidth = w), (viewHeight = h))"
      @move="(x, y) => (viewCenter = { x, y })"
      @start-drag="refreshCursor"
      @stop-drag="refreshCursor"
      @mousedown.native.prevent="e => onPress(e) && onMouseDown(e, true)"
      @mousemove.native="onMouseMove"
      @mouseout.native="e => !e.buttons && (pointerPos = null)"
      @mousewheel.native.prevent="e => onMouseWheel(e, true)"
      @touchstart.native.prevent="e => onPress(e) && onTouchStart(e, true)"
      @touchend.native="e => (pointerPos = null)"
      @touchcancel.native="e => (pointerPos = null)"
      v-touch-pan.mouse.preserveCursor="onDrag"
      @hook:mounted="viewRefresh++"
    >
      <div class="absolute-center text-h3 text-center" style="width: 300px">视图内容</div>
    </ZoomView>
  </div>
</template>

<script>
// 【主视图区】
import { mapGetters } from 'vuex'
import { mapStateRW, exposeChildMethods } from 'boot/utils'
import { KEY } from 'boot/constants'
import key from 'keymaster'

export default {
  data: () => ({
    viewRefresh: 1 // 视图子组件刷新计数（用于手动刷新视图子组件相关计算属性）
  }),

  computed: {
    ...mapStateRW('main', ['viewZoom']),
    ...mapGetters('main', ['maxViewZoom', 'minViewZoom']),
    ...mapStateRW('edit', ['viewWidth', 'viewHeight', 'viewCenter', 'viewAim', 'pointerPos']),

    // 是否正在拖拽视图
    isDragging() {
      if (!this.viewRefresh || !this.$refs.view) return
      return !!this.$refs.view.dragState
    }
  },

  provide() {
    return {
      page: this
    }
  },

  watch: {
    // 切换鼠标光标
    isDragging: 'refreshCursor',

    // 指定视图中心要对准的位置
    viewAim(val) {
      if (val == null) return
      this.$refs.view.updateViewCenter(this.viewAim.x, this.viewAim.y)
      this.viewAim = null // 重置以响应下次指定
    }
  },

  methods: {
    ...exposeChildMethods('view', ['onMouseDown', 'onMouseWheel', 'onTouchStart']),

    // 按下处理
    // - @return 是否继续处理视图交互
    onPress(e) {
      this.$clearFocus()
      const xy = this.onMouseMove(e)
      if (key.isPressed(KEY.SPACE)) return true // 空格键按下时改为拖拽地图（避免元件太多时点不到地图没法拖拽）

      // ...
      if (xy) return true

      return false
    },

    // 拖拽处理
    onDrag(e) {
      this.onMouseMove(e.evt)

      // ...
    },

    // 鼠标移动处理
    // - @return 视图坐标
    onMouseMove(e) {
      e = e.touches ? e.touches[0] || e.changedTouches[0] : e // 触点放开时没有touches，因此要改用changedTouches
      const xy = this.$refs.view.pageToViewXY(e.pageX, e.pageY)
      const [x, y] = xy.map(Math.round)
      if (!this.pointerPos || this.pointerPos.x !== x || this.pointerPos.y !== y) {
        this.pointerPos = { x, y }
      }

      // ...

      return xy
    },

    // 刷新鼠标光标
    refreshCursor() {
      this.$setCursor(this.isDragging ? 'grabbing' : '')
    }
  },

  mounted() {
    if (process.env.DEBUGGING) {
      window.$m = this
    }

    // 绑定快捷键
    key.setScope('main')
  }
}
</script>
